<template>
    <div class="dict-management-container">
        <el-card shadow="hover">
            <!-- 搜索区域 -->
            <div class="search-container">
                <el-form :model="queryParams" inline>
                    <el-form-item label="字典编码">
                        <el-input v-model="queryParams.dictCode" placeholder="请输入字典编码" clearable
                            @keyup.enter="handleSearch" />
                    </el-form-item>
                    <el-form-item label="字典名称">
                        <el-input v-model="queryParams.dictName" placeholder="请输入字典名称" clearable
                            @keyup.enter="handleSearch" />
                    </el-form-item>
                    <el-form-item label="字典类型">
                        <el-select v-model="queryParams.dictType" placeholder="请选择字典类型" clearable>
                            <el-option v-for="item in dictTypeOptions" :key="item.value" :label="item.label"
                                :value="item.value" />
                        </el-select>
                    </el-form-item>
                    <el-form-item>
                        <el-button type="primary" @click="handleSearch">
                            <el-icon>
                                <Search />
                            </el-icon>搜索
                        </el-button>
                        <el-button @click="resetQuery">
                            <el-icon>
                                <Refresh />
                            </el-icon>重置
                        </el-button>
                    </el-form-item>
                </el-form>
            </div>

            <!-- 操作按钮 -->
            <div class="operation-container">
                <el-button type="primary" @click="handleAdd">
                    <el-icon>
                        <Plus />
                    </el-icon>新增
                </el-button>
                <el-button type="danger" :disabled="multipleSelection.length === 0" @click="handleBatchDelete">
                    <el-icon>
                        <Delete />
                    </el-icon>删除
                </el-button>
            </div>

            <!-- 表格区域 -->
            <el-table v-loading="loading" :data="dictList" border @selection-change="handleSelectionChange">
                <el-table-column type="selection" width="55" align="center" />
                <el-table-column prop="dictCode" label="字典编码" width="180" show-overflow-tooltip />
                <el-table-column prop="dictName" label="字典名称" width="180" show-overflow-tooltip />
                <el-table-column prop="dictType" label="字典类型" width="120">
                    <template #default="{ row }">
                        <el-tag :type="row.dictType === 'system' ? 'danger' : 'success'">
                            {{ row.dictType === "system" ? "系统" : "业务" }}
                        </el-tag>
                    </template>
                </el-table-column>
                <el-table-column prop="dictValue" label="字典值" width="120" />
                <el-table-column prop="dictLabel" label="字典标签" />
                <el-table-column prop="sort" label="排序" width="80" align="center" />
                <el-table-column prop="status" label="状态" width="100" align="center">
                    <template #default="{ row }">
                        <el-switch v-model="row.status" :active-value="1" :inactive-value="0"
                            @change="handleStatusChange(row)" />
                    </template>
                </el-table-column>
                <el-table-column prop="createTime" label="创建时间" width="180" align="center" />
                <el-table-column label="操作" width="180" align="center" fixed="right">
                    <template #default="{ row }">
                        <el-button size="small" type="text" @click="handleEdit(row)" v-has-permi="['system:dict:edit']">
                            <el-icon>
                                <Edit />
                            </el-icon>编辑
                        </el-button>
                        <el-button size="small" type="text" @click="handleDelete(row)"
                            v-has-permi="['system:dict:remove']">
                            <el-icon>
                                <Delete />
                            </el-icon>删除
                        </el-button>
                    </template>
                </el-table-column>
            </el-table>

            <!-- 分页区域 -->
            <div class="pagination-container">
                <el-pagination v-model:current-page="queryParams.pageNum" v-model:page-size="queryParams.pageSize"
                    :page-sizes="[10, 20, 30, 50]" layout="total, sizes, prev, pager, next, jumper" :total="total"
                    @size-change="handleSizeChange" @current-change="handleCurrentChange" />
            </div>
        </el-card>

        <!-- 新增/编辑对话框 -->
        <el-dialog v-model="dialog.visible" :title="dialog.title" width="600px" append-to-body>
            <el-form ref="dictFormRef" :model="formData" :rules="rules" label-width="100px">
                <el-form-item label="字典编码" prop="dictCode">
                    <el-input v-model="formData.dictCode" placeholder="请输入字典编码" :disabled="dialog.isEdit" />
                </el-form-item>
                <el-form-item label="字典名称" prop="dictName">
                    <el-input v-model="formData.dictName" placeholder="请输入字典名称" />
                </el-form-item>
                <el-form-item label="字典类型" prop="dictType">
                    <el-select v-model="formData.dictType" placeholder="请选择字典类型" style="width: 100%">
                        <el-option v-for="item in dictTypeOptions" :key="item.value" :label="item.label"
                            :value="item.value" />
                    </el-select>
                </el-form-item>
                <el-form-item label="字典值" prop="dictValue">
                    <el-input v-model="formData.dictValue" placeholder="请输入字典值" />
                </el-form-item>
                <el-form-item label="字典标签" prop="dictLabel">
                    <el-input v-model="formData.dictLabel" placeholder="请输入字典标签" />
                </el-form-item>
                <el-form-item label="排序" prop="sort">
                    <el-input-number v-model="formData.sort" controls-position="right" :min="0" style="width: 100%" />
                </el-form-item>
                <el-form-item label="状态" prop="status">
                    <el-radio-group v-model="formData.status">
                        <el-radio :label="1">启用</el-radio>
                        <el-radio :label="0">禁用</el-radio>
                    </el-radio-group>
                </el-form-item>
                <el-form-item label="备注" prop="remark">
                    <el-input v-model="formData.remark" type="textarea" placeholder="请输入备注" :rows="3" />
                </el-form-item>
            </el-form>
            <template #footer>
                <div class="dialog-footer">
                    <el-button @click="dialog.visible = false">取 消</el-button>
                    <el-button type="primary" @click="submitForm">确 定</el-button>
                </div>
            </template>
        </el-dialog>
    </div>
</template>

<script lang="ts" setup>
import { ref, reactive, onMounted } from "vue"
import { ElMessage, ElMessageBox } from "element-plus"
import {
    Search,
    Refresh,
    Plus,
    Delete,
    Edit
} from "@element-plus/icons-vue"
import type { FormInstance, FormRules } from "element-plus"
import {
    listDict,
    getDict,
    addDict,
    updateDict,
    deleteDict,
    changeDictStatus
} from "@/api/system/dict"

// 字典类型选项
const dictTypeOptions = [
    { value: "system", label: "系统" },
    { value: "business", label: "业务" }
]

// 查询参数
const queryParams = reactive({
    pageNum: 1,
    pageSize: 10,
    dictCode: "",
    dictName: "",
    dictType: ""
})

// 表格数据
const dictList = ref<any[]>([])
const total = ref(0)
const loading = ref(false)
const multipleSelection = ref<any[]>([])

// 表单数据
const formData = reactive({
    id: undefined,
    dictCode: "",
    dictName: "",
    dictType: "business",
    dictValue: "",
    dictLabel: "",
    sort: 0,
    status: 1,
    remark: ""
})

// 表单验证规则
const rules = reactive<FormRules>({
    dictCode: [
        { required: true, message: "字典编码不能为空", trigger: "blur" },
        { min: 2, max: 64, message: "长度在2到64个字符之间", trigger: "blur" }
    ],
    dictName: [
        { required: true, message: "字典名称不能为空", trigger: "blur" },
        { min: 2, max: 64, message: "长度在2到64个字符之间", trigger: "blur" }
    ],
    dictType: [
        { required: true, message: "请选择字典类型", trigger: "change" }
    ],
    dictValue: [
        { required: true, message: "字典值不能为空", trigger: "blur" }
    ],
    dictLabel: [
        { required: true, message: "字典标签不能为空", trigger: "blur" }
    ],
    sort: [
        { required: true, message: "排序不能为空", trigger: "blur" }
    ]
})

// 对话框配置
const dialog = reactive({
    visible: false,
    title: "",
    isEdit: false
})

const dictFormRef = ref<FormInstance>()

// 获取字典列表
const getList = async () => {
    try {
        loading.value = true
        const res: any = await listDict(queryParams)
        dictList.value = res.data.list
        total.value = res.data.total
    } finally {
        loading.value = false
    }
}

// 搜索
const handleSearch = () => {
    queryParams.pageNum = 1
    getList()
}

// 重置查询
const resetQuery = () => {
    queryParams.pageNum = 1
    queryParams.dictCode = ""
    queryParams.dictName = ""
    queryParams.dictType = ""
    getList()
}

// 表格选择项变化
const handleSelectionChange = (selection: any[]) => {
    multipleSelection.value = selection
}

// 分页大小变化
const handleSizeChange = (val: number) => {
    queryParams.pageSize = val
    getList()
}

// 当前页变化
const handleCurrentChange = (val: number) => {
    queryParams.pageNum = val
    getList()
}

// 状态变化
const handleStatusChange = async (row: any) => {
    try {
        await changeDictStatus(row.id, row.status)
        ElMessage.success("状态修改成功")
    } catch {
        row.status = row.status === 1 ? 0 : 1
    }
}

// 新增
const handleAdd = () => {
    dialog.visible = true
    dialog.title = "新增字典"
    dialog.isEdit = false
    resetForm()
}

// 编辑
const handleEdit = async (row: any) => {
    try {
        const res: any = await getDict(row.id)
        Object.assign(formData, res.data)
        dialog.visible = true
        dialog.title = "修改字典"
        dialog.isEdit = true
    } catch (error) {
        console.error(error)
    }
}

// 删除
const handleDelete = (row: any) => {
    ElMessageBox.confirm(`确认要删除字典编码为"${row.dictCode}"的数据项吗?`, "警告", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning"
    }).then(async () => {
        await deleteDict(row.id)
        ElMessage.success("删除成功")
        getList()
    }).catch(() => { })
}

// 批量删除
const handleBatchDelete = () => {
    const ids = multipleSelection.value.map(item => item.id)
    ElMessageBox.confirm(`确认要删除选中的${ids.length}条数据吗?`, "警告", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning"
    }).then(async () => {
        await deleteDict(ids)
        ElMessage.success("删除成功")
        getList()
    }).catch(() => { })
}

// 重置表单
const resetForm = () => {
    dictFormRef.value?.resetFields()
    formData.id = undefined
    formData.dictCode = ""
    formData.dictName = ""
    formData.dictType = "business"
    formData.dictValue = ""
    formData.dictLabel = ""
    formData.sort = 0
    formData.status = 1
    formData.remark = ""
}

// 提交表单
const submitForm = async () => {
    await dictFormRef.value?.validate()

    try {
        if (dialog.isEdit) {
            await updateDict(formData)
            ElMessage.success("修改成功")
        } else {
            await addDict(formData)
            ElMessage.success("新增成功")
        }
        dialog.visible = false
        getList()
    } catch (error) {
        console.error(error)
    }
}

onMounted(() => {
    getList()
})
</script>

<style lang="scss" scoped>
.dict-management-container {
    padding: 20px;

    .search-container {
        margin-bottom: 20px;
    }

    .operation-container {
        margin-bottom: 20px;
    }

    .pagination-container {
        margin-top: 20px;
        text-align: center;
    }
}
</style>